﻿#define _CRT_SECURE_NO_WARNINGS 1


//整数在内存中的存储

//正整数的原、反、补码都相同

//负整数的三种表⽰⽅法各不相同。
//原码：直接将数值按照正负数的形式翻译成⼆进制得到的就是原码。
//反码：将原码的符号位不变，其他位依次按位取反就可以得到反码。
//补码：反码 + 1就得到补码。


//什么是⼤⼩端？
//⼤端（存储）模式：
//是指数据的低位字节内容保存在内存的⾼地址处，⽽数据的⾼位字节内容，保存在内存的低地址处。
//⼩端（存储）模式：
//是指数据的低位字节内容保存在内存的低地址处，⽽数据的⾼位字节内容，保存在内存的⾼地址处。


////练习1
////设计⼀个⼩程序来判断当前机器的字节序。
//#include<stdio.h>
//int check_sys()
//{
//	int n = 1;
//	return *((char*)&n);
//}
//int main()
//{
//	int ret = check_sys();
//	if (1 == ret)
//		printf("小端\n");
//	else
//		printf("大端\n");
//
//
//	return 0;
//}




////练习2
//#include <stdio.h>
//int main()
//{
//	char a = -1;
//	//10000000000000000000000000000001 --- 原码
//	//11111111111111111111111111111110 --- 反码
//	//11111111111111111111111111111111 --- 补码
//	//11111111
//	//11111111111111111111111111111111
//	signed char b = -1;
//	//10000000000000000000000000000001 --- 原码
//	//11111111111111111111111111111110 --- 反码
//	//11111111111111111111111111111111 --- 补码
//	//11111111
//	//11111111111111111111111111111111
//	unsigned char c = -1;
//	//10000000000000000000000000000001 --- 原码
//	//11111111111111111111111111111110 --- 反码
//	//11111111111111111111111111111111 --- 补码
//	//11111111
//	//00000000000000000000000011111111
//	printf("a=%d,b=%d,c=%d", a, b, c);// -1 -1 255
//
//	return 0;
//}


//练习3
////#include <stdio.h>
////int main()
////{
////	char a = -128;
////	//10000000000000000000000010000000 --- 原码
////	//11111111111111111111111101111111 --- 反码
////	//11111111111111111111111110000000 --- 补码
////	//10000000
////	//11111111111111111111111110000000
////	printf("%u\n", a);//
////	return 0;
////}
//
//
//#include <stdio.h>
//int main()
//{
//	char a = 128;
//	//00000000000000000000000010000000 --- 原码
//	//01111111111111111111111101111111 --- 反码
//	//01111111111111111111111110000000 --- 反码
//	//10000000 
//	//11111111111111111111111110000000 
//	printf("%u\n", a);
//	return 0;
//}


//练习4
//#include <stdio.h>
//int main()
//{
//	char a[1000];
//	int i;
//	for (i = 0; i < 1000; i++)
//	{
//		a[i] = -1 - i;   // -1 -2 -3 ... -128 127 126 ... 3 2 1 0 -1 -2 -3 ...
//	}
//	printf("%d", strlen(a)); // 255
//	return 0;
//}


////练习5
////#include <stdio.h>
////unsigned char i = 0;// 0 ~ 255
////int main()
////{
////	for (i = 0; i <= 255; i++)//死循环
////	{
////		printf("hello world\n");
////	}
////	return 0;
////}
//
//#include <stdio.h>
//#include<Windows.h>
//int main()
//{
//	unsigned int i;// 4,294,967,295~0
//	for (i = 9; i >= 0; i--)//死循环
//	{
//		printf("%u\n", i);
//		Sleep(1000);
//	}
//	return 0;
//}


////练习6
//#include <stdio.h>
////X86环境 ⼩端字节序
//int main()
//{
//	int a[4] = { 1, 2, 3, 4 };
//	// 01 00 00 00   02 00 00 00   03 00 00 00   04 00 00 00 	
//	int* ptr1 = (int*)(&a + 1);
//	int* ptr2 = (int*)((int)a + 1);
//	printf("%#x,%#x", ptr1[-1], *ptr2);// 0x4 0x2000000
//
//	return 0;
//}


//浮点数在内存中的存储

//根据国际标准IEEE（电⽓和电⼦⼯程协会） 754，任意⼀个⼆进制浮点数V可以表⽰成下⾯的形式：
//V = (−1)∗ S *M ∗ 2^E
//•(−1)S 表⽰符号位，当S = 0，V为正数；当S = 1，V为负数
//• M 表⽰有效数字，M是⼤于等于1，⼩于2的
//• 2^E
//E 表⽰指数位

//IEEE 754规定：
//对于32位的浮点数，最⾼的1位存储符号位S，接着的8位存储指数E，剩下的23位存储有效数字M
//对于64位的浮点数，最⾼的1位存储符号位S，接着的11位存储指数E，剩下的52位存储有效数字M

//E为⼀个⽆符号整数（unsigned int）
//IEEE 754规定，存⼊内存时E的真实值必须再加上
//⼀个中间数，对于8位的E，这个中间数是127；对于11位的E，这个中间数是1023

//E全为0
//浮点数的指数E等于1 - 127（或者1 - 1023）即为真实值，有效数字M不再加上第⼀位的1，⽽是还
//原为0.xxxxxx的⼩数

//E全为1,无穷大

//练习
#include <stdio.h>
int main()
{
	int n = 9;
	//00000000000000000000000000001001
	//00000000000000000000000000001001
	//00000000000000000000000000001001 --- 补码
	float* pFloat = (float*)&n;
	// 0 00000000 00000000000000000001001

	printf("n的值为：%d\n", n);// 9 
	printf("*pFloat的值为：%f\n", *pFloat);// 0.000000

	

	*pFloat = 9.0; 
	//0 10000010 00100000000000000000000
	printf("num的值为：%d\n", n);// 1,091,567,616
	printf("*pFloat的值为：%f\n", *pFloat);// 9.0
	return 0;
}






